/*------------------------------------------------------------------------
//                          Project CommonLib                           //
------------------------------------------------------------------------*/


#pragma once


namespace Str_Util
{
	inline char * WideToANSI(int codepage, const WCHAR * wideText, char * ansiText, int ansiTextBufferSize)
	{
		::WideCharToMultiByte(codepage, 0, wideText, -1, ansiText, ansiTextBufferSize, NULL, NULL);
		return ansiText;
	}

	inline WCHAR * AnsiToWide(int codepage, const char * ansiText, WCHAR * wideText, int wideTextBufferSize)
	{
		::MultiByteToWideChar(codepage, 0, ansiText, -1, wideText, wideTextBufferSize);
		return wideText;
	}

	inline int WideToAnsiSize(int codepage, const WCHAR * wideText)
	{
		return ::WideCharToMultiByte(codepage, 0, wideText, -1, NULL, 0, NULL, NULL);
	}

	inline int AnsiToWideSize(int codepage, const char* ansiText)
	{
		return ::MultiByteToWideChar(codepage, 0, ansiText, -1, NULL, 0);
	}

	inline bool ConverCHAR2WCHAR( WCHAR* wstrDestination, const CHAR* strSource, int nDestChatLength )
	{
		if( NULL == wstrDestination || NULL == strSource || nDestChatLength < 1 )
			return false;

		int nResult = ::MultiByteToWideChar( CP_ACP, 0, strSource, -1, 
			wstrDestination, nDestChatLength );
		wstrDestination[nDestChatLength-1] = 0;

		if( nResult == 0 )
			return false;
		return true;
	}

	inline bool ConverWCHAR2CHAR( CHAR* strDestination, const WCHAR* wstrSource, int nDestChatLength )
	{
		if( NULL == strDestination || NULL == wstrSource || nDestChatLength < 1 )
			return false;

		int nResult = ::WideCharToMultiByte( CP_ACP, 0, wstrSource, -1, strDestination, 
			nDestChatLength*sizeof(CHAR), NULL, NULL );
		strDestination[nDestChatLength-1] = 0;

		if( nResult == 0 )
			return false;
		return true;
	}
	}

#define _StackAllock(size) ((size==0) ? 0 : _alloca((size+7)&~7))
#define _STRW2A(text) Str_Util::WideToANSI(CP_ACP, text, (CHAR*)_StackAllock(Str_Util::WideToAnsiSize(CP_ACP, text) * sizeof(CHAR)), Str_Util::WideToAnsiSize(CP_ACP, text))
#define _STRA2W(text) Str_Util::AnsiToWide(CP_ACP, text, (WCHAR*)_StackAllock(Str_Util::AnsiToWideSize(CP_ACP, text) * sizeof(WCHAR)), Str_Util::AnsiToWideSize(CP_ACP, text))





//to ansi
#ifndef TCHAR_TO_ANSI
	#define TCHAR_TO_ANSI(str) _STRW2A(str)
#endif

//to uni
#ifndef ANSI_TO_TCHAR
	#define ANSI_TO_TCHAR(str) _STRA2W(str)
#endif




/*------------------------------------------------------------------------

------------------------------------------------------------------------*/
 